package com.econ.powercloud.ems.service.biz;

import com.econ.powercloud.clickhouse.entity.EmsStatisticalMonth;
import com.econ.powercloud.clickhouse.entity.EmsStatisticalYear;
import com.econ.powercloud.common.base.facade.util.JacksonUtil;
import com.econ.powercloud.ems.common.enums.IncomeDayReportLocationDesc;
import com.econ.powercloud.ems.common.enums.IncomeReportType;
import com.econ.powercloud.ems.common.enums.ReportIdType;
import com.econ.powercloud.ems.common.util.DateTimeUtil;
import com.econ.powercloud.ems.config.EMSStaticMap;
import com.econ.powercloud.ems.constant.SysConstant;
import com.econ.powercloud.ems.dal.entity.EmsColumnConfigDevice;
import com.econ.powercloud.ems.domain.EmsColumnConfigDeviceDO;
import com.econ.powercloud.ems.pojo.EmsColumnConfigDeviceVO;
import com.econ.powercloud.ems.pojo.IncomeColumnVO;
import com.econ.powercloud.ems.pojo.IncomeReportVO;
import com.econ.powercloud.ems.pojo.requestVO.ReportRequestVO;
import com.econ.powercloud.ems.service.dao.EmsColumnConfigDeviceDAO;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author : zjf
 * @Description : 受益报表service
 * @Date : 2021/10/21 10:19
 * @Modified by : zjf
 */
@Service
public class IncomeReportService {

    @Autowired
    private EmsColumnConfigDeviceDAO emsColumnConfigDeviceDAO;
    @Autowired
    private ClickHouseBizService clickHouseBizService;

    /**
     * 获取储能装置 受益日报表
     * map的 key: 和前端商量之后的列对应的id,value:每一位置的名称
     */
    public List<Map<String,String>> getEquipmentDayData(String stationId,String equipmentId,String reportId,Long startTime){
        List<Map<String,String>> result = Lists.newArrayList();
        //获取日报表的所有列数据
        List<EmsColumnConfigDevice> columnConfigDevices = emsColumnConfigDeviceDAO.selectListByReportIdAndReportType(reportId, IncomeReportType.DAILY.getCode());
        List<EmsColumnConfigDeviceVO> configDeviceVOS = EmsColumnConfigDeviceDO.entityListToVOList(columnConfigDevices);
        //获取当天的表中所有数据
//        List<EmsStatisticalMonth> statisticalMonthList = emsStatisticalMonthDAO.getListByCondition(stationId,equipmentId,null,reportId,startTime,startTime);
        ReportRequestVO requestVO = ReportRequestVO.builder().stationId(stationId)
                .equipmentId(equipmentId).reportId(reportId).startTime(startTime).endTime(startTime).build();
        List<EmsStatisticalMonth> statisticalMonthList = clickHouseBizService.getMonthDataByCondition(requestVO);
        Map<String, EmsStatisticalMonth> statisticalMonthMap = statisticalMonthList.stream().collect(Collectors.toMap(EmsStatisticalMonth::getColumnId, p->p,(p1, p2)->p1));
        //按照行进行分组
        Map<Integer,List<EmsColumnConfigDeviceVO>> configDeviceMap = configDeviceVOS.stream().collect(Collectors.groupingBy(d->d.getCross()));
        //获取表头(目前是存在EMSStaticMap中,项目初始化时加载)
        List<String> incomeDayReportHead = EMSStaticMap.incomeDayReportHead;
        //分别获取每一行中的数据
        for (int i=1; i<=configDeviceMap.keySet().size(); i++){
            Map<String,String> map = Maps.newLinkedHashMap();
            List<EmsColumnConfigDeviceVO> list = CollectionUtils.isNotEmpty(configDeviceMap.get(i))?configDeviceMap.get(i): Lists.newArrayList();
            //key:列的位置
            Map<Integer, EmsColumnConfigDeviceVO> deviceVOMap = list.stream().collect(Collectors.toMap(EmsColumnConfigDeviceVO::getGroup, p->p,(p1, p2)->p1));
            //在按照类别,项目,本期示数等表头分装数据
            for (int j=1; j<=incomeDayReportHead.size(); j++){
                if(deviceVOMap.get(j) != null){
                    EmsStatisticalMonth emsStatisticalMonth = statisticalMonthMap.get(deviceVOMap.get(j).getColumnId());
                    map.put(incomeDayReportHead.get(j-1),emsStatisticalMonth == null ? null : emsStatisticalMonth.getVal());
                }else{
                    map.put(incomeDayReportHead.get(j-1), IncomeDayReportLocationDesc.getDescFromCode(i + SysConstant.CABLE + j));
                }
            }
            result.add(map);
        }
        return result;
    }


    /**
     * 获取受益报表月报表数据
     */
    public IncomeReportVO getIncomeDataByMonth(String stationId, String equipmentId, String reportId, Long startTime){
        Long endOfMonth = DateTimeUtil.getEndOfMonth(new Date(startTime));
        List<Map<String,String>> bodyList = Lists.newLinkedList();
        if(StringUtils.isEmpty(reportId)){
            reportId = ReportIdType.INCOME.getCode();
        }
        //获取报表列信息并排序
        List<EmsColumnConfigDevice> emsColumnConfigDevices = emsColumnConfigDeviceDAO.selectListByReportIdAndReportType(reportId, IncomeReportType.MONTH_AND_YEAR.getCode());
        List<IncomeColumnVO> incomeColumnVOList = emsColumnConfigDevices.stream().map(m -> IncomeColumnVO.builder().columnId(m.getColumnId()).sorting(Integer.valueOf(m.getSorting())).build())
                .collect(Collectors.toList());
        List<IncomeColumnVO> incomeColumnVOListSort = incomeColumnVOList.stream().sorted(Comparator.comparing(IncomeColumnVO::getSorting)).collect(Collectors.toList());
        List<String> columnIdList = emsColumnConfigDevices.stream().map(EmsColumnConfigDevice::getColumnId).collect(Collectors.toList());
//        List<EmsStatisticalMonth> listByColumnId = emsStatisticalMonthDAO.getListByColumnId(stationId, equipmentId, reportId, columnIdList, startTime, endOfMonth);
        ReportRequestVO requestVO = ReportRequestVO.builder().stationId(stationId).columnIdList(columnIdList)
                .equipmentId(equipmentId).reportId(reportId).startTime(startTime).endTime(endOfMonth).build();
        List<EmsStatisticalMonth> listByColumnId = clickHouseBizService.getMonthDataByCondition(requestVO);

        //按行列顺序排序结果数据
        List<EmsStatisticalMonth> incomeDataMonthListSort = Lists.newLinkedList();
        Map<String, List<EmsStatisticalMonth>> IncomeDataMonthForColumnId = listByColumnId.stream().collect(Collectors.groupingBy(d -> d.getColumnId()));
        for (IncomeColumnVO incomeColumnVO : incomeColumnVOListSort) {
            List<EmsStatisticalMonth> incomeDataMonthList = IncomeDataMonthForColumnId.get(incomeColumnVO.getColumnId());
            if(null != incomeDataMonthList){
                incomeDataMonthListSort.addAll(incomeDataMonthList);
            }
        }
        //报表数据按照时间进行分组
        Map<Long,List<EmsStatisticalMonth>> statisticalDayMap = incomeDataMonthListSort.stream().collect(Collectors.groupingBy(d->d.getTime(),LinkedHashMap::new,Collectors.toList()));
        statisticalDayMap = statisticalDayMap.entrySet().stream().sorted(Map.Entry.comparingByKey()).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
                (oleValue, newValue) -> oleValue, LinkedHashMap::new));
        statisticalDayMap.forEach((k,v)->{
            Map<String,String> map = Maps.newLinkedHashMap();
            //把日期那一列的数据放入
            map.put(SysConstant.DATE, DateTimeUtil.formatDate(new Date(k), DateTimeUtil.DAY_PATTERN));
            v.stream().forEach(d->{
                map.put(d.getColumnId(),d.getVal());
            });
            bodyList.add(map);
        });
        //增加总计计算
        DecimalFormat doubleFormatter = new DecimalFormat("0.00");
        doubleFormatter.setRoundingMode(RoundingMode.HALF_UP);
        Map<String,String> sumMap = Maps.newLinkedHashMap();
        sumMap.put("date","总计");
        for (String columnId : columnIdList) {
            double sum = bodyList.stream().mapToDouble(map2 -> map2.get(columnId) == null ? 0.0:Double.parseDouble(map2.get(columnId))).sum();
            if (("Epp1".equals(columnId) || "Enp1".equals(columnId)) && sum == 0.0) {
                continue;
            }
            sumMap.put(columnId,doubleFormatter.format(sum));
        }
        bodyList.add(sumMap);
        IncomeReportVO incomeReportVO = IncomeReportVO.builder().bodyList(bodyList).build();
        return incomeReportVO;
    }

    /**
     * 获取受益报表年报表数据
     */
    public IncomeReportVO getIncomeDataByYear(String stationId, String equipmentId, String reportId, Long startTime){
        Long endOfMonth = DateTimeUtil.getEndOfYear(new Date(startTime));
        List<Map<String,String>> bodyList = Lists.newLinkedList();
        if(StringUtils.isEmpty(reportId)){
            reportId = ReportIdType.INCOME.getCode();
        }
        //获取报表列信息并排序
        List<EmsColumnConfigDevice> emsColumnConfigDevices = emsColumnConfigDeviceDAO.selectListByReportIdAndReportType(reportId, IncomeReportType.MONTH_AND_YEAR.getCode());
        List<IncomeColumnVO> incomeColumnVOList = emsColumnConfigDevices.stream().map(m -> IncomeColumnVO.builder().columnId(m.getColumnId()).sorting(Integer.valueOf(m.getSorting())).build())
                .collect(Collectors.toList());
        List<IncomeColumnVO> incomeColumnVOListSort = incomeColumnVOList.stream().sorted(Comparator.comparing(IncomeColumnVO::getSorting)).collect(Collectors.toList());
        List<String> columnIdList = emsColumnConfigDevices.stream().map(EmsColumnConfigDevice::getColumnId).collect(Collectors.toList());
//        List<EmsStatisticalYear> listByColumnId = emsStatisticalYearDAO.getListByColumnId(stationId, equipmentId, reportId, columnIdList, startTime, endOfMonth);
        ReportRequestVO requestVO = ReportRequestVO.builder().stationId(stationId).columnIdList(columnIdList)
                .equipmentId(equipmentId).reportId(reportId).startTime(startTime).endTime(endOfMonth).build();
        List<EmsStatisticalYear> listByColumnId = clickHouseBizService.getYearDataByCondition(requestVO);

        //按行列顺序排序结果数据
        List<EmsStatisticalYear> incomeDataYearListSort = Lists.newLinkedList();
        Map<String, List<EmsStatisticalYear>> IncomeDataYearForColumnId = listByColumnId.stream().collect(Collectors.groupingBy(d -> d.getColumnId()));
        for (IncomeColumnVO incomeColumnVO : incomeColumnVOListSort) {
            List<EmsStatisticalYear> incomeDataYearList = IncomeDataYearForColumnId.get(incomeColumnVO.getColumnId());
            if(null != incomeDataYearList){
                incomeDataYearListSort.addAll(incomeDataYearList);
            }
        }
        //报表数据按照时间进行分组
        Map<Long,List<EmsStatisticalYear>> statisticalDayMap = incomeDataYearListSort.stream().collect(Collectors.groupingBy(d->d.getTime(),LinkedHashMap::new,Collectors.toList()));
        statisticalDayMap = statisticalDayMap.entrySet().stream().sorted(Map.Entry.comparingByKey()).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
                (oleValue, newValue) -> oleValue, LinkedHashMap::new));
        statisticalDayMap.forEach((k,v)->{
            Map<String,String> map = Maps.newLinkedHashMap();
            //把日期那一列的数据放入
            map.put(SysConstant.DATE, DateTimeUtil.formatDate(new Date(k), DateTimeUtil.MONTH_PATTERN));
            v.stream().forEach(d->{
                map.put(d.getColumnId(),d.getVal());
            });
            bodyList.add(map);
        });
        //增加总计计算
        DecimalFormat doubleFormatter = new DecimalFormat("0.00");
        doubleFormatter.setRoundingMode(RoundingMode.HALF_UP);
        Map<String,String> sumMap = Maps.newLinkedHashMap();
        sumMap.put("date","总计");
        for (String columnId : columnIdList) {
            double sum = bodyList.stream().mapToDouble(map2 -> map2.get(columnId) == null ? 0.0:Double.parseDouble(map2.get(columnId))).sum();
            if (("Epp1".equals(columnId) || "Enp1".equals(columnId)) && sum == 0.0) {
                continue;
            }
            sumMap.put(columnId,doubleFormatter.format(sum));
        }
        bodyList.add(sumMap);
        IncomeReportVO incomeReportVO = IncomeReportVO.builder().bodyList(bodyList).build();
        return incomeReportVO;
    }

}
